/*
 * macros.h
 *
 *  Created on: 2013-6-20
 *  Author: xnan
 */

#ifndef XNL_XNMACROS_H_
#define XNL_XNMACROS_H_

#include <cstddef>

// XNL lib namespace
#define XNL_NAMESPACE xnl

#define NS_XNL_BEGIN namespace XNL_NAMESPACE {
#define NS_XNL_END }

// do...while
#define DOWHILE( p ) do { p }while(0)

// memory manager
#define XN_DELETE( p ) DOWHILE( if( p ) { delete (p); } )
#define XN_DELETE_NULL( p ) DOWHILE( if( p ) { delete (p); (p) = NULL; } )
#define XN_DELETE_ARRAY( p ) DOWHILE( if( p ) { delete[] (p); } )
#define XN_DELETE_ARRAY_NULL( p ) DOWHILE( if( p ) { delete[] (p); (p) = NULL; } )

#define XN_RELEASE( p ) DOWHILE( if( p ) { (p)->release(); } )
#define XN_RELEASE_NULL( p ) DOWHILE( if( p ) { (p)->release(); (p) = NULL; } )
#define XN_RETAIN( p ) DOWHILE( if( p ) { (p)->retain(); } )
#define XN_RETAIN_ASSIGN( p_left, p_right ) \
    DOWHILE( (p_left) = (p_right); ); \
    XN_RETAIN( p_left )
#define XN_RETAIN_SWAP( p_old, p_new ) \
    XN_RELEASE( p_old );\
    XN_RETAIN_ASSIGN( p_old, p_new )

// diagnosis message generate
#ifdef _DEBUG

#   define __XN_ERR_STR( p_prefix, p_str, p_file, p_line ) p_prefix#p_file":"#p_line" -- "p_str
#   define _XN_ERR_STR( p_prefix, p_str, p_file, p_line ) __XN_ERR_STR( p_prefix, p_str, p_file, p_line )
#   define XN_ERR_STR( p_prefix, p_str ) _XN_ERR_STR( p_prefix, p_str, __FILE__, __LINE__ )
#   define XN_RUNTIME_ERR_STR( p_str ) XN_ERR_STR( "Runtime error at ", p_str )

#else

#   define __XN_ERR_STR( p_prefix, p_str, p_file, p_line ) p_prefix#p_file":"#p_line" -- "p_str
#   define _XN_ERR_STR( p_prefix, p_str, p_file, p_line ) __XN_ERR_STR( p_prefix, p_str, p_file, p_line )
#   define XN_ERR_STR( p_prefix, p_str ) _XN_ERR_STR( p_prefix, p_str, __FILE__, __LINE__ )

#   define XN_RUNTIME_ERR_STR( p_str ) XN_ERR_STR( "Runtime error at ", p_str )
/*#   define __XN_ERR_STR( p_prefix, p_str, p_file, p_line ) p_prefix""p_str
#   define _XN_ERR_STR( p_prefix, p_str, p_file, p_line ) __XN_ERR_STR( p_prefix, p_str, p_file, p_line )
#   define XN_ERR_STR( p_prefix, p_str ) _XN_ERR_STR( p_prefix, p_str, __FILE__, __LINE__ )
#   define XN_RUNTIME_ERR_STR( p_str ) XN_ERR_STR( "Runtime error: ", p_str )*/

#endif

#endif /* XNL_XNMACROS_H_ */
